package com.wangdao.wechatmall.pointcut;

import com.wangdao.wechatmall.bean.bo.AuthLoginBO;
import com.wangdao.wechatmall.bean.pojo.Log;
import com.wangdao.wechatmall.mapper.AdminMapper;
import com.wangdao.wechatmall.mapper.LogMapper;
import com.wangdao.wechatmall.util.IpUtils;
import lombok.SneakyThrows;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.Date;

/**
 * @ClassName: SystemPointCut
 * @Description ${DESCRIPTION}
 * @Author Xinhao Yi
 * @Date 2021/7/13  20:37
 */
    @Aspect
    @Component
    public class SystemPointCut {

        @Autowired
        AdminMapper adminMapper;

        @Autowired
        LogMapper logMapper;

        @Pointcut("execution(* com..admin.AdminControlController.*(..))")
        public void pointcut() {
        }

        @Pointcut("execution(* com..admin.AuthController.log*(..))")
        public void pointcut1() {
        }

        @SneakyThrows
        @Around("pointcut()")
        public Object adminMethodAround(ProceedingJoinPoint joinPoint) {
            Log log = new Log();
            Object[] args = joinPoint.getArgs();
            //
            if (args.length != 2){
                //如果参数个数不是两个，也就是不是两个形参，说明增强的函数错了，直接放行
                Object proceed = joinPoint.proceed();
                return proceed;
            }
            Object admin = args[0];
            //反射
            Field field = admin.getClass().getDeclaredField("username");
            field.setAccessible(true);
            //result是创建的新的名字/修改后的新的名字/
            String result = (String) field.get(admin);
            HttpServletRequest request = (HttpServletRequest) args[1];
            String ip = IpUtils.getIpAddr(request);

            //拿到当前的管理员
            Subject subject = SecurityUtils.getSubject();
            String username = (String) subject.getPrincipals().getPrimaryPrincipal();
            log.setAdmin(username);

            //拿到方法名
            Signature signature = joinPoint.getSignature();
            String action = signature.getName();
            if (action.endsWith("update")) {
                log.setAction("编辑管理员");
            } else if (action.endsWith("delete")) {
                log.setAction("删除管理员");
            } else if (action.endsWith("create")) {
                log.setAction("添加管理员");
            }

            log.setIp(ip);
            log.setResult(result);
            log.setAddTime(new Date());
            log.setUpdateTime(new Date());
            log.setComment("");
            log.setStatus(true);
            log.setType(1);
            logMapper.insertSelective(log);

            Object proceed = joinPoint.proceed();
            return proceed;
        }

        @SneakyThrows
        @Around("pointcut1()")
        public Object adminLogMethodAround(ProceedingJoinPoint joinPoint) {

            Log log = new Log();
            Object[] args = joinPoint.getArgs();

            HttpServletRequest request = (HttpServletRequest) args[0];
            String ip = IpUtils.getIpAddr(request);

            Signature signature = joinPoint.getSignature();
            String action = signature.getName();

            Object proceed = null;

            if (action.contains("login")) {
                proceed = joinPoint.proceed();
                Field field = proceed.getClass().getDeclaredField("errmsg");
                field.setAccessible(true);
                String msg = (String) field.get(proceed);
                log.setAction("登录");
                if ("成功".equals(msg)) {
                    AuthLoginBO authLoginBo = (AuthLoginBO) args[1];
                    log.setAdmin(authLoginBo.getUsername());
                    log.setStatus(true);
                } else {
                    log.setAdmin("匿名用户");
                    log.setStatus(false);
                    log.setResult(msg);
                }
            } else if (action.contains("logout")) {
                //拿到当前的管理员
                Subject subject = SecurityUtils.getSubject();
                String username = (String) subject.getPrincipals().getPrimaryPrincipal();
                log.setAdmin(username);
                proceed = joinPoint.proceed();
                log.setAction("退出");
                log.setStatus(true);
            }

            log.setIp(ip);
            log.setAddTime(new Date());
            log.setUpdateTime(new Date());
            log.setComment("");
            log.setType(1);

            logMapper.insertSelective(log);
            return proceed;
        }
}
